package sensorBoard.sensor;

import java.io.IOException;
import java.util.Vector;

import sensorBoard.ISensorBoardComponent;
import server.interfaces.ISensorBoardManager;

import com.CharNotValidException;
import com.Event;
import com.LedsManager;
import com.ParamNotFoundException;
import com.ParamsLabel;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.resources.transducers.ILightSensor;
import com.sun.spot.resources.transducers.LEDColor;

/**
 * Provides the access to the node Light sensor. Provides information about the light values 
 * and builds instances of LightListener if it's necessary.
 * @author Francesco Aiello, Antonio Guerrieri, Raffaele Gravina
 *
 */
public class LightSensor implements ISensorBoardComponent {
	
	private byte [] handlableEvents = {Event.LGH_CURRENT, 
			Event.LGH_THRESHOLDCHANGED, 
			Event.LGH_THRESHOLDEXCEDEED,
			Event.LGH_TERMINATION};
	private ILightSensor lightSensor;
	private ISensorBoardManager sensorBoardManager;
	private Vector lightListeners;
	
	/**
	 * The constructor needs to know own sensorBoardManager and the Light Sensor class provided by SunSPOT SDK
	 * @param sensorBoardManager own sensorBoardManager
	 */
	public LightSensor (ISensorBoardManager sensorBoardManager) {
		this.sensorBoardManager = sensorBoardManager;
		this.lightSensor = EDemoBoard.getInstance().getLightSensor();
		this.lightListeners = new Vector();
	}
	
	public boolean IsEventHandlable(byte eventName) {
		for (int i = 0; i < handlableEvents.length; i++) 
			if (this.handlableEvents[i] == eventName)
				return true;
		return false;
	}
	
	public void handleEvent(Event event) {
		
		
		try {
			byte eventName = event.getName();
			switch (eventName) {
				case Event.LGH_CURRENT:
					if (event.getType() == Event.NOW) {
						event.setParam(ParamsLabel.LGH_LIGHT_VALUE, "" + this.lightSensor.getValue());
						this.sensorBoardManager.send(event);
					}
				break;
				case Event.LGH_THRESHOLDEXCEDEED:
					if (event.getType() != Event.NOW && this.lightListeners.size() == 0) {
						String sensorID = this.sensorBoardManager.generateSensorBoardComponentID();
						this.lightListeners.addElement(new LightListener(this, sensorID, event));
						Event sensorIDEvent = new Event("", event.getTargetID(), Event.LGH_ID, Event.NOW);
						sensorIDEvent.setParam(ParamsLabel.SNS_ID, sensorID);
						this.sensorBoardManager.send(sensorIDEvent);
					}
					else {
						Event sensorBoardComponentNotAvailableEvent = new Event("", event.getTargetID(), Event.LGH_NOT_AVAILABLE, Event.NOW);
						this.sensorBoardManager.send(sensorBoardComponentNotAvailableEvent);
					}
				break;
				case Event.LGH_TERMINATION:
					String sensorID;
					try {
						sensorID = event.getParam(ParamsLabel.SNS_ID);
						if (!sensorID.equals("")) {
							if (this.terminateListener(sensorID))
								this.sensorBoardManager.send(event);
						}
					}
					catch (ParamNotFoundException e) {
						LedsManager.error(LEDColor.YELLOW);
						e.printStackTrace();
					}
				break;
				
			}
		}
		catch (IOException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
		catch (CharNotValidException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
		
	}
	
	public void send(Event backEvent) {
		this.sensorBoardManager.send(backEvent);
	}
	
	public boolean terminateListener(String sensorID) {
		for (int i = 0; i < this.lightListeners.size(); i++) {
			LightListener lightListener = (LightListener)this.lightListeners.elementAt(i);
			if ( lightListener.getSensorBoardComponentID().equals(sensorID) ) {
				this.lightListeners.removeElementAt(i);
				return lightListener.terminateListener(); 
			}
		}
		return false;
	}
	
}


